home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / kant-generator-04-c / Kant ƒ / Shell ƒ / help.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  10.2 KB  |  417 lines  |  [TEXT/MMCC]

  1. #include "help.h"
  2. #include "environment.h"
  3. #include "popup.h"
  4. #include "util.h"
  5. #include "buttons.h"
  6. #include "styled text.h"
  7. #include "program globals.h"
  8.  
  9. #define DEAD_SPACE_TOP        10
  10. #define DEAD_SPACE_LEFT        10
  11. #define DEAD_SPACE_BOTTOM    5
  12. #define DEAD_SPACE_RIGHT    10
  13. #define    TEXT_RECT_WIDTH        405
  14. #define    TEXT_RECT_HEIGHT    250
  15. #define    BUTTON_WIDTH        80
  16. #define    BUTTON_HEIGHT        17
  17. #define BUTTON_GAP_H        15
  18. #define BUTTON_GAP_V        5
  19.  
  20. #define MAX_MAIN_TOPICS        5
  21. #define    MAX_SUB_TOPICS        10
  22.  
  23. #define    MAX_XREFS            6
  24.  
  25. #define MAIN_TOPIC_ID        600
  26. #define POPUP_MENU_ID        100
  27.  
  28. short            gNumMainTopics;
  29. short            gNumSubTopics[MAX_MAIN_TOPICS];
  30. short            gNumXRefs[MAX_MAIN_TOPICS][MAX_SUB_TOPICS];
  31.  
  32. Str31            gMainTopicTitle[MAX_MAIN_TOPICS];
  33. Rect            gMainTopicRect[MAX_MAIN_TOPICS];
  34.  
  35. Str31            gSubTopicTitle[MAX_MAIN_TOPICS][MAX_SUB_TOPICS];
  36. short            gSubTopicID[MAX_MAIN_TOPICS][MAX_SUB_TOPICS];
  37.  
  38. short            gXRefIndex[MAX_MAIN_TOPICS][MAX_SUB_TOPICS][MAX_XREFS];
  39. Rect            gXRefRect[MAX_XREFS];
  40.  
  41. short            gMainTopicShowing;        /* saved in prefs file */
  42. short            gSubTopicShowing;        /* saved in prefs file */
  43.  
  44. Rect            gTextRect;
  45. CharHandle        gTheText;
  46. StylHandle        gTheStyle;
  47.  
  48. /*-----------------------------------------------------------------------------------*/
  49. /* internal stuff for help.c                                                         */
  50.  
  51. static    void SetupTheHelpWindow(WindowDataHandle theData);
  52. static    void ShutdownTheHelpWindow(WindowDataHandle theData);
  53. static    void InitializeTheHelpWindow(WindowDataHandle theData);
  54. static    void OpenTheHelpWindow(WindowDataHandle theData);
  55. static    void KeyPressedInHelpWindow(WindowDataHandle theData, unsigned char keyPressed);
  56. static    void MouseClickedInHelpWindow(WindowDataHandle theData, Point mouseLoc);
  57. static    void DrawTheHelpWindow(short theDepth);
  58. static    short ParseRawTitle(Str255 theTitle, short *xRef, short *numXRefs);
  59. static    void GoToPage(WindowDataHandle theData, short mainTopic, short subTopic,
  60.                 Boolean updateNow);
  61. static    void PushInSubTopic(WindowDataHandle theData);
  62. static    void PullOutSubTopic(WindowDataHandle theData, short mainTopic);
  63. static    void GetTextResources(short mainTopic, short subTopic);
  64. static    void DisposeTextResources(void);
  65. static    void CalculateXRefInfo(short index, short *mainTopic, short *subTopic,
  66.                 Str255 name);
  67.  
  68.  
  69. short HelpWindowDispatch(WindowDataHandle theData, short theMessage, unsigned long misc)
  70. {
  71.     unsigned char    theChar;
  72.     Point            thePoint;
  73.     short            theDepth;
  74.     
  75.     switch (theMessage)
  76.     {
  77.         case kUpdate:
  78.             theDepth=misc&0x7fff;
  79.             DrawTheHelpWindow(theDepth);
  80.             return kSuccess;
  81.             break;
  82.         case kKeydown:
  83.             theChar=misc&charCodeMask;
  84.             KeyPressedInHelpWindow(theData, theChar);
  85.             return kSuccess;
  86.             break;
  87.         case kMousedown:
  88.             thePoint.h=(misc>>16)&0x7fff;
  89.             thePoint.v=misc&0x7fff;
  90.             MouseClickedInHelpWindow(theData, thePoint);
  91.             return kSuccess;
  92.             break;
  93.         case kOpen:
  94.             OpenTheHelpWindow(theData);
  95.             return kSuccess;
  96.             break;
  97.         case kInitialize:
  98.             InitializeTheHelpWindow(theData);
  99.             return kSuccess;
  100.             break;
  101.         case kStartup:
  102.             SetupTheHelpWindow(theData);
  103.             return kSuccess;
  104.             break;
  105.         case kShutdown:
  106.             ShutdownTheHelpWindow(theData);
  107.             return kSuccess;
  108.             break;
  109.     }
  110.     
  111.     return kFailure;        /* revert to default processing for all other messages */
  112. }
  113.  
  114. void SetupTheHelpWindow(WindowDataHandle theData)
  115. {
  116.     short            i,j;
  117.     unsigned char    *helpStr="\pHelp";
  118.     Handle            temp;
  119.     short            strID;
  120.     
  121.     temp=GetResource('STR#', MAIN_TOPIC_ID);
  122.     gNumMainTopics=**((short**)temp);
  123.     ReleaseResource(temp);
  124.     for (i=0; i<gNumMainTopics; i++)
  125.     {
  126.         GetIndString(gMainTopicTitle[i], MAIN_TOPIC_ID, i+1);
  127.         strID=ParseRawTitle(gMainTopicTitle[i], 0L, 0L);
  128.         
  129.         for (j=0; j<5; j++)
  130.             gMainTopicTitle[i][++gMainTopicTitle[i][0]]=' ';
  131.         
  132.         SetRect(    &gMainTopicRect[i],
  133.                     DEAD_SPACE_LEFT+(BUTTON_WIDTH+BUTTON_GAP_H)*i,
  134.                     DEAD_SPACE_TOP,
  135.                     DEAD_SPACE_LEFT+(BUTTON_WIDTH+BUTTON_GAP_H)*i+BUTTON_WIDTH,
  136.                     DEAD_SPACE_TOP+BUTTON_HEIGHT);
  137.         
  138.         temp=GetResource('STR#', strID);
  139.         gNumSubTopics[i]=**((short**)temp);
  140.         ReleaseResource(temp);
  141.         
  142.         for (j=0; j<gNumSubTopics[i]; j++)
  143.         {
  144.             GetIndString(gSubTopicTitle[i][j], strID, j+1);
  145.             gSubTopicID[i][j]=ParseRawTitle(gSubTopicTitle[i][j], gXRefIndex[i][j],
  146.                 &(gNumXRefs[i][j]));
  147.         }
  148.     }
  149.     
  150.     gTheText=0L;
  151.     gTheStyle=0L;
  152.     GoToPage(0L, gMainTopicShowing, gSubTopicShowing, FALSE);
  153.     
  154.     SetRect(&gTextRect, DEAD_SPACE_LEFT, DEAD_SPACE_TOP+BUTTON_HEIGHT+BUTTON_GAP_V,
  155.         DEAD_SPACE_LEFT+TEXT_RECT_WIDTH,
  156.         DEAD_SPACE_TOP+BUTTON_HEIGHT+BUTTON_GAP_V+TEXT_RECT_HEIGHT);
  157.     
  158.     (**theData).maxDepth=8;
  159.     (**theData).windowWidth=DEAD_SPACE_LEFT+TEXT_RECT_WIDTH+DEAD_SPACE_RIGHT;
  160.     (**theData).windowHeight=BUTTON_GAP_V+DEAD_SPACE_TOP+BUTTON_HEIGHT+TEXT_RECT_HEIGHT+
  161.         DEAD_SPACE_BOTTOM;
  162.     (**theData).windowType=noGrowDocProc;    /* document-looking thing */
  163.     (**theData).hasCloseBox=TRUE;
  164.     (**theData).windowBounds.top=50;
  165.     (**theData).windowBounds.left=6;
  166.     SetIndWindowTitle(kHelpWindow, helpStr);
  167.     
  168. //    if (gIsVirgin)
  169. //        OpenTheIndWindow((**theData).windowIndex);
  170. }
  171.  
  172. void ShutdownTheHelpWindow(WindowDataHandle theData)
  173. {
  174.     DisposeTextResources();
  175. }
  176.  
  177. void InitializeTheHelpWindow(WindowDataHandle theData)
  178. {
  179.     (**theData).initialTopLeft.v=(**theData).windowBounds.top-9;
  180.     (**theData).initialTopLeft.h=(**theData).windowBounds.left;
  181. }
  182.  
  183. void OpenTheHelpWindow(WindowDataHandle theData)
  184. {
  185.     (**theData).offscreenNeedsUpdate=TRUE;
  186. }
  187.  
  188. void KeyPressedInHelpWindow(WindowDataHandle theData, unsigned char keyPressed)
  189. {
  190.     ObscureCursor();
  191.     
  192.     switch (keyPressed)
  193.     {
  194.         case 0x1d:                                        /* right arrow */
  195.             gSubTopicShowing++;
  196.             if (gSubTopicShowing>=gNumSubTopics[gMainTopicShowing])
  197.             {
  198.                 gSubTopicShowing=0;
  199.                 gMainTopicShowing++;
  200.                 if (gMainTopicShowing>=gNumMainTopics)
  201.                     gMainTopicShowing=0;
  202.             }
  203.             GoToPage(theData, gMainTopicShowing, gSubTopicShowing, TRUE);
  204.             break;
  205.         case 0x1c:                                        /* left arrow */
  206.             gSubTopicShowing--;
  207.             if (gSubTopicShowing<0)
  208.             {
  209.                 gMainTopicShowing--;
  210.                 if (gMainTopicShowing<0)
  211.                     gMainTopicShowing=gNumMainTopics-1;
  212.                 gSubTopicShowing=gNumSubTopics[gMainTopicShowing]-1;
  213.             }
  214.             GoToPage(theData, gMainTopicShowing, gSubTopicShowing, TRUE);
  215.             break;
  216.     }
  217. }
  218.  
  219. void MouseClickedInHelpWindow(WindowDataHandle theData, Point mouseLoc)
  220. {
  221.     short            i;
  222.     Str255            name;
  223.     short            newMain, newSub;
  224.     MenuHandle        theMenu;
  225.     Rect            menuRect;
  226.     
  227.     for (i=0; i<gNumXRefs[gMainTopicShowing][gSubTopicShowing]; i++)
  228.     {
  229.         if (PtInRect(mouseLoc, &gXRefRect[i]))
  230.         {
  231.             CalculateXRefInfo(gXRefIndex[gMainTopicShowing][gSubTopicShowing][i],
  232.                 &newMain, &newSub, name);
  233.             
  234.             if ((newMain!=-1) && (newSub!=-1))
  235.             {
  236.                 if (Track3DButton(&gXRefRect[i], name, 0L, (**theData).windowDepth, TRUE))
  237.                 {
  238.                     GoToPage(theData, newMain, newSub, TRUE);
  239.                     return;
  240.                 }
  241.             }
  242.         }
  243.     }
  244.     
  245.     newMain=-1;
  246.     
  247.     for (i=0; i<gNumMainTopics; i++)
  248.     {
  249.         if (PtInRect(mouseLoc, &gMainTopicRect[i]))
  250.         {
  251.             newMain=i;
  252.             i=gNumMainTopics;
  253.         }
  254.     }
  255.     
  256.     if (newMain!=-1)
  257.     {
  258.         Draw3DButton(&gMainTopicRect[newMain], gMainTopicTitle[newMain], 0L,
  259.             (**theData).windowDepth, TRUE, TRUE);
  260.         
  261.         theMenu=NewMenu(POPUP_MENU_ID, "\p");
  262.         for (i=0; i<gNumSubTopics[newMain]; i++)
  263.         {
  264.             AppendMenu(theMenu, gSubTopicTitle[newMain][i]);
  265.             CheckItem(theMenu, i+1, ((newMain==gMainTopicShowing) && (i==gSubTopicShowing)));
  266.         }
  267.         
  268.         menuRect.top=gMainTopicRect[newMain].bottom-1;
  269.         menuRect.left=gMainTopicRect[newMain].left+1;
  270.         newSub=-1;
  271.         if (MouseInModelessPopUp(theMenu, &newSub, &menuRect, POPUP_MENU_ID))
  272.         {
  273.             GoToPage(theData, newMain, newSub-1, TRUE);
  274.         }
  275.         else
  276.         {
  277.             Draw3DButton(&gMainTopicRect[newMain], gMainTopicTitle[newMain], 0L,
  278.                 (**theData).windowDepth, FALSE, TRUE);
  279.         }
  280.         
  281.         DisposeHandle((Handle)theMenu);
  282.     }
  283. }
  284.  
  285. void DrawTheHelpWindow(short theDepth)
  286. {
  287.     GrafPtr            curPort;
  288.     short            i;
  289.     Rect            tempRect;
  290.         
  291.     GetPort(&curPort);
  292.     EraseRect(&(curPort->portRect));
  293.     
  294.     DrawTheShadowBox(gTextRect, TRUE);
  295.     if (gTheText!=0L)
  296.     {
  297.         tempRect=gTextRect;
  298.         InsetRect(&tempRect, 8, 4);
  299.         DrawTheText(gTheText, gTheStyle, kLeft, srcOr, tempRect);
  300.     }
  301.     
  302.     for (i=0; i<gNumMainTopics; i++)
  303.     {
  304.         Draw3DButton(&gMainTopicRect[i], gMainTopicTitle[i], 0L, theDepth, FALSE, TRUE);
  305.     }
  306.     
  307. }
  308.  
  309. short ParseRawTitle(Str255 theTitle, short *xRef, short *numXRefs)
  310. {
  311.     Str255            numStr;
  312.     long            result;
  313.     short            i,j;
  314.     Boolean            gotbullet;
  315.     Boolean            moreXRefs;
  316.     
  317.     if (xRef!=0L)
  318.     {
  319.         *numXRefs=0;
  320.         for (j=1, gotbullet=FALSE; ((j<=theTitle[0]) && (!gotbullet)); j++)
  321.             gotbullet=(theTitle[j]=='%');
  322.         if (gotbullet)
  323.         {
  324.             i=j;
  325.             do
  326.             {
  327.                 numStr[0]=0x00;
  328.                 while ((numStr[0]<=theTitle[0]-i) &&
  329.                     (((numStr[numStr[0]]=theTitle[i+(numStr[0]++)]))!=' ')) {}
  330.                 if (numStr[numStr[0]]==' ')
  331.                 {
  332.                     moreXRefs=TRUE;
  333.                     i+=numStr[0];
  334.                     numStr[0]--;
  335.                 }
  336.                 else moreXRefs=FALSE;
  337.                 StringToNum(numStr, &result);
  338.                 xRef[(*numXRefs)++]=result;
  339.             }
  340.             while (moreXRefs);
  341.             theTitle[0]=j-2;
  342.         }
  343.     }
  344.     numStr[0]=0x00;
  345.     while ((numStr[numStr[0]]=theTitle[++numStr[0]])!=' ') {}
  346.     theTitle[0]-=numStr[0];
  347.     Mymemcpy((Ptr)&theTitle[1], (Ptr)&theTitle[numStr[0]+1], theTitle[0]);
  348.     numStr[0]--;
  349.     StringToNum(numStr, &result);
  350.     return result;
  351. }
  352.  
  353. void GoToPage(WindowDataHandle theData, short mainTopic, short subTopic,
  354.     Boolean updateNow)
  355. {
  356.     DisposeTextResources();
  357.     GetTextResources(mainTopic, subTopic);
  358.     gMainTopicShowing=mainTopic;
  359.     gSubTopicShowing=subTopic;
  360.     if (updateNow)
  361.     {
  362.         (**theData).offscreenNeedsUpdate=TRUE;
  363.         UpdateTheWindow((ExtendedWindowDataHandle)theData);
  364.     }
  365. }
  366.  
  367. void GetTextResources(short mainTopic, short subTopic)
  368. {
  369.     short            resID;
  370.     
  371.     DisposeTextResources();
  372.     resID=gSubTopicID[mainTopic][subTopic];
  373.     gTheText=(CharHandle)GetResource('TEXT', resID);
  374.     gTheStyle=(StylHandle)GetResource('styl', resID);
  375. }
  376.  
  377. void DisposeTextResources(void)
  378. {
  379.     if (gTheText!=0L)
  380.         ReleaseResource((Handle)gTheText);
  381.     if (gTheStyle!=0L)
  382.         ReleaseResource((Handle)gTheStyle);
  383.     gTheText=0L;
  384.     gTheStyle=0L;
  385. }
  386.  
  387. void CalculateXRefInfo(short index, short *mainTopic, short *subTopic, Str255 name)
  388. {
  389.     short            theMain, theSub;
  390.     unsigned char    *bad="\pBad XRef!";
  391.     
  392.     theMain=gNumMainTopics-1;
  393.     theSub=gNumSubTopics[theMain]-1;
  394.     while ((theMain>=0) && (index!=gSubTopicID[theMain][theSub]))
  395.     {
  396.         theSub--;
  397.         if (theSub<0)
  398.         {
  399.             theMain--;
  400.             theSub=gNumSubTopics[theMain];
  401.         }
  402.     }
  403.     
  404.     if (theMain<0)
  405.     {
  406.         Mymemcpy((Ptr)name, (Ptr)bad, bad[0]+1);
  407.         *mainTopic=*subTopic=-1;
  408.     }
  409.     else
  410.     {
  411.         Mymemcpy((Ptr)name, (Ptr)gSubTopicTitle[theMain][theSub],
  412.             gSubTopicTitle[theMain][theSub][0]+1);
  413.         *mainTopic=theMain;
  414.         *subTopic=theSub;
  415.     }
  416. }
  417.